﻿import flash.display.BitmapData;
import kliment.geom.BoundsRectangle;
import kliment.geom.SimplePoint;
import kliment.utils._Type;

/**
 * ...
 * @author	Kliment
 * @version	2.10.3
 */

class kliment.display.MCC {
	static public var namePreffix:String = "dynamic_mc";
	static private var index:Number = 0;
	
	static public function create(target_mc:MovieClip, name:String):MovieClip {
		target_mc = _getTarget(target_mc);
		name = _getName(name);
		return target_mc.createEmptyMovieClip(name, target_mc.getNextHighestDepth());
	}
	
	static public function attach(identifer:String, target_mc:MovieClip, name:String):MovieClip {
		if (!identifer)	return null;
		target_mc = _getTarget(target_mc);
		name = _getName(name);
		return target_mc.attachMovie(identifer, name, target_mc.getNextHighestDepth());
	}
	
	static public function duplicate(target_mc:MovieClip, name:String, initObject:Object):MovieClip {
		target_mc = _getTarget(target_mc);
		name = _getName(name);
		return target_mc.duplicateMovieClip(name, target_mc._parent.getNextHighestDepth(),  initObject);
	}
	
	static public function attachClass(target_mc:MovieClip, className:Function, argumentsArray:Array):Object {
		if (!target_mc || !className) 
			return null;
		target_mc.__proto__ = className.prototype;
		className.apply(target_mc, argumentsArray || null);
		return target_mc;
	}
	
	static public function attachBitmap(target_mc:MovieClip, bitmap:BitmapData,  pixelSnapping:String, smoothing:Boolean):MovieClip {
		target_mc.attachBitmap(bitmap, target_mc.getNextHighestDepth(),  pixelSnapping, smoothing);
		return target_mc;
	}
	
	static public function remove(victim:MovieClip):Void {
		victim.onEnterFrame = null;
		if (victim.getDepth() < 0)
			victim.swapDepths(victim._parent.getNextHighestDepth());
		victim.removeMovieClip();
	}
	
	static private function _getTarget(target:MovieClip):MovieClip {
		if (!target) return _root;
		return target;
	}
	
	static private function _getName(name:String):String {
		if (!name) return namePreffix + index++;
		return name;
	}
	
	static public function clear(target:MovieClip):Void {
		for (var i in  target) 
			remove(target[i])
		target.clear();
	}
	
	static public function hitTestMouse(target_mc:MovieClip):Boolean {
		var parent_mc:MovieClip = target_mc._parent;
		return hitTestPoint(target_mc, parent_mc._xmouse, parent_mc._ymouse);
	}
	
	static public function hitTestPoint(target_mc:MovieClip, x:Number, y:Number):Boolean {
		if (!_Type.isMovieClip(target_mc)) 
			return false;
		var parent_mc:MovieClip = target_mc._parent;
		var p:SimplePoint = new SimplePoint(x, y);
		if (parent_mc)
			parent_mc.localToGlobal(p);
		return target_mc.hitTest(p.x, p.y, true);
	}
	
	static public function hitTestBoundsMouse(target_mc:MovieClip):Boolean {
		var parent_mc:MovieClip = target_mc._parent;
		return hitTestBounds(target_mc, parent_mc._xmouse, parent_mc._ymouse);
	}
	
	static public function hitTestBounds(target_mc:MovieClip, x:Number, y:Number):Boolean {
		if (!_Type.isMovieClip(target_mc)) 
			return false;
		var bounds:BoundsRectangle = getBounds(target_mc);
		if (bounds.includePoint(new SimplePoint(x, y))) 
			return true;
		return false;
	}
	
	static public function getBounds(target_mc:MovieClip):BoundsRectangle {
		return toBounds(target_mc.getBounds(target_mc._parent));
	}
	
	static public function getRect(target_mc:MovieClip):BoundsRectangle {
		return toBounds(target_mc.getRect(target_mc._parent));
	}
	
	static public function toBounds(target:Object):BoundsRectangle {
		return new BoundsRectangle(target['xMin'], target['yMin'], target['xMax'], target['yMax']);
	}
	
	static public function toMCProperties(value:Object):Object {
		var result:Object = new Object();
		for (var i in value) {
			if (!(value[i] instanceof Object))
				result['_' + i] = value[i];
		}
		return result;
	}
	
	static public function getFrameByName(target_mc:MovieClip, frame_name:String):Number {
		if (!target_mc) return NaN;
		var f_frame = target_mc._currentframe;
		target_mc.gotoAndStop(frame_name);
		var frameNum:Number = target_mc._currentframe;
		target_mc.gotoAndStop(f_frame);
		return frameNum;
	}
	
	static public function translatePosition(target_mc:MovieClip, to_mc:MovieClip):SimplePoint {
		if (!target_mc || !to_mc) return null;
		var point:SimplePoint = new SimplePoint();
		target_mc.localToGlobal(point);
		to_mc.globalToLocal(point);
		return point;
	}
	
	static public function widthScale(target_mc:MovieClip, value:Number):Number {
		if (!target_mc) return NaN;
		target_mc._width = value || 1;
		target_mc._yscale = target_mc._xscale;
		return target_mc._height;
	}
	
	static public function heightScale(target_mc:MovieClip, value:Number):Number {
		if (!target_mc) return NaN;
		target_mc._height = value || 1;
		target_mc._xscale = target_mc._yscale;
		return target_mc._width;
	}
	
	/**
	 * 
	 * @param	MovieClip target_mc
	 * @return	Number Old depth value
	 */
	static public function swapDepthsTop(target_mc:MovieClip):Number {
		if (!target_mc) return NaN;
		var depth:Number = target_mc.getDepth();
		target_mc.swapDepths(target_mc._parent.getNextHighestDepth());
		return depth;
	}
	
	static public function getSharedParent(movie_clips:Array):MovieClip {
		var delimer:String = '.';
		var pathsArray:Array = new Array();
		var parentPath:Array = new Array();
		var currentStr:String;
		var prevtStr:String;
		var equal:Boolean = true;
		var step:Number = 0;
		var length:Number = movie_clips.length;
		var i:Number;
		for (i = 0; i < length; ++i) 
			pathsArray.push(String(movie_clips[i]).split(delimer));
		while (equal) {
			for (i = 1; i < length; ++i) {
				currentStr = pathsArray[i][step];
				prevtStr = pathsArray[i - 1][step];
				if (currentStr != prevtStr || step >= pathsArray[i].length){
					equal = false;
					break;
				}
			}
			if (equal){
				parentPath.push(currentStr);
				++step;
			}
		}
		return eval(parentPath.join(delimer)) || _root;
	}
}